from pml import PML
from pml import Objects

class Frame(Objects.object.typeobject):
    def __init__(self, id='', bytecodes=None, stack=None, variable={}, const={}, index=0, father=None, stdio=None):
        super().__init__('frame')
        self.id = id
        self.bytecodes = None if bytecodes is None else (bytecodes if isinstance(bytecodes, list) else bytecodes.obj)
        self.stack = stack
        self.variable = variable
        self.const = const
        self.index = index - 1
        self.father = father
        self.stdio = stdio
    def __repr__(self):
        return f'Frame(name={self.id})'

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        self.methods['getNextBytecode'] = self.getNextBytecode
        self.methods['jump'] = self.jump
        self.methods['copy'] = self.copy

        return self

    def getMember(self, member):
        try:
            return self.const[member]
        except KeyError:
            try:
                return self.variable[member]
            except KeyError:
                raise NameError(self.id, member)

    def getStaticMember(self, member):
        return self.getMember(member)

    @staticmethod
    def getNextBytecode(frame, this: 'Frame', position):
        this.index += 1
        try:
            return this.bytecodes[this.index]
        except IndexError:
            raise StopIteration()

    @staticmethod
    def jump(frame, this: 'Frame', position, index):
        this.index = index - 2
        return this.getNextBytecode(frame, this, position)

    @staticmethod
    def copy(frame, this: 'Frame', position):
        return Objects.object.PMTypeObject(Frame(this.id, this.bytecodes, this.stack, this.variable, this.const, 0, this.father))

    @staticmethod
    def tp_init(frame, this, position):
        pass
